package com.xbongbong.paas.service.workflow.detail;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xbongbong.formula.constant.Constant;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.FieldAttrConstant;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasFormRichTextEntity;
import com.xbongbong.paas.domain.entity.PaasFormSubDataEntity;
import com.xbongbong.paas.domain.entity.ext.FieldPermissionEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.EnableEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.NodeTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.enums.ProcessTypeEnum;
import com.xbongbong.paas.enums.SheetTypeEnum;
import com.xbongbong.paas.enums.TaskTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.help.BusinessUserTeamHelp;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.EsignHelp;
import com.xbongbong.paas.help.FormDataHelp;
import com.xbongbong.paas.help.FormExplainHelp;
import com.xbongbong.paas.help.FormatDataHelp;
import com.xbongbong.paas.help.OwnerAndCoUserHelp;
import com.xbongbong.sys.help.PackageHelp;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.help.UserInfoHelp;
import com.xbongbong.paas.help.WorkflowHelp;
import com.xbongbong.paas.help.WorkflowNodeHelp;
import com.xbongbong.paas.help.WorkflowOperateHelp;
import com.xbongbong.paas.help.service.impl.FormDataLinkDataUpdateGetServiceImpl;
import com.xbongbong.paas.help.team.FormTeamSetHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.dto.FormDataUpdateGetDTO;
import com.xbongbong.paas.pojo.dto.ParseSingleRowDataDTO;
import com.xbongbong.paas.pojo.vo.LinkResultDataVO;
import com.xbongbong.paas.pojo.vo.PaasProcessNodeTaskVO;
import com.xbongbong.paas.pojo.vo.ParseSingleRowDataVO;
import com.xbongbong.paas.pojo.vo.ProcessOperateVo;
import com.xbongbong.paas.pojo.vo.ProcessTemplateNodeVO;
import com.xbongbong.paas.pojo.workflow.task.dto.WorkflowNodeTaskGetDTO;
import com.xbongbong.paas.pojo.workflow.task.vo.WorkflowNodeTaskGetVO;
import com.xbongbong.paas.service.dingtalkTodo.WorkflowDingtalkTodoService;
import com.xbongbong.paas.service.workflow.approveListPage.WorkflowApproveListPageService;
import com.xbongbong.paas.service.workflow.comment.WorkflowCommentService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.pojo.PermissionTermsPojo;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.WorkflowValidateUtil;
import com.xbongbong.parent.explain.FormDataFormExplainHandleName;
import com.xbongbong.parent.parse.data.FormDataUpdateGetAnalysisDataHelp;
import com.xbongbong.pro.businessdata.pojo.dto.FormatExplainDTO;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.domain.entity.FormTeamSetEntity;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.RichTextEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.PrintProPermissionAliasEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.enums.teammembers.enums.FormOwnerUniqueEnum;
import com.xbongbong.pro.enums.teammembers.enums.FormPatternEnum;
import com.xbongbong.pro.esign.pojo.dto.EsignFlowStatusDTO;
import com.xbongbong.pro.esign.pojo.vo.EsignFlowStatusVO;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.formdata.pojo.SaasSpecialParamPojo;
import com.xbongbong.pro.formdata.pojo.dto.SaasAnalysisDataDTO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.pro.help.UserConfigHelp;
import com.xbongbong.pro.user.pojo.ReturnUserAndDepartmentPojo;
import com.xbongbong.pro.workflow.enums.WorkflowOperateEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.InvoiceConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.PaymentConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.constant.teammembers.TeamMembersConstant;
import com.xbongbong.saas.domain.entity.CouponEntity;
import com.xbongbong.saas.domain.entity.InvoiceExpressSubDataEntity;
import com.xbongbong.saas.domain.entity.PublicGroupSeniorEntity;
import com.xbongbong.saas.domain.entity.WorkOrderFormEntity;
import com.xbongbong.saas.domain.entity.WorkOrderTemplateEntity;
import com.xbongbong.saas.domain.entity.ext.ContractEntityExt;
import com.xbongbong.saas.domain.entity.ext.WorkOrderExplainEntityExt;
import com.xbongbong.saas.enums.EsignFlowStatusEnum;
import com.xbongbong.saas.enums.InvoiceTitleTypeEnum;
import com.xbongbong.saas.enums.ShowTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.InventoryEnum;
import com.xbongbong.saas.enums.business.InvoiceEnum;
import com.xbongbong.saas.enums.business.OrderEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.PurchaseInvoiceEnum;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.saas.enums.business.ReturnEnum;
import com.xbongbong.saas.enums.business.SupplierContactEnum;
import com.xbongbong.saas.enums.business.WorkOrderEnum;
import com.xbongbong.saas.help.FormatProductHelp;
import com.xbongbong.saas.help.FundHelp;
import com.xbongbong.saas.help.InvoiceCommonHelp;
import com.xbongbong.saas.help.ShowFormatHelp;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.CouponModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.InvoiceExpressSubDataModel;
import com.xbongbong.saas.model.InvoiceModel;
import com.xbongbong.saas.model.PaasFormRichTextModel;
import com.xbongbong.saas.model.PublicGroupSeniorModel;
import com.xbongbong.saas.model.PurchaseInvoiceModel;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.saas.model.WorkOrderFormModel;
import com.xbongbong.saas.model.WorkOrderTemplateModel;
import com.xbongbong.saas.service.toolbox.help.FundMoneyHelp;
import com.xbongbong.saas.service.toolbox.help.FundSetHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.help.ProPermissionHelp;
import com.xbongbong.sys.model.DepartmentModel;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.util.ContractCompareUtil;
import com.xbongbong.util.ProcessUtil;
import com.xbongbong.workflow.domain.entity.WorkflowEntity;
import com.xbongbong.workflow.domain.entity.WorkflowTaskEntity;
import com.xbongbong.workflow.domain.entity.WorkflowTaskNodeEntity;
import com.xbongbong.workflow.domain.entity.WorkflowTransferDataEntity;
import com.xbongbong.workflow.domain.entity.ext.WorkflowNodeEntityExt;
import com.xbongbong.workflow.domain.entity.ext.WorkflowTaskNodeEntityExt;
import com.xbongbong.workflow.model.WorkflowModel;
import com.xbongbong.workflow.model.WorkflowNodeModel;
import com.xbongbong.workflow.model.WorkflowTaskModel;
import com.xbongbong.workflow.model.WorkflowTaskNodeModel;
import com.xbongbong.workflow.model.WorkflowTransferDataModel;
import com.xbongbong.workflow.pojo.WorkflowTransferPOJO;
import com.xbongbong.workflow.pojo.nodes.ApprovalNode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author 吴峰
 * @date 2023/01/06 9:45
 */
@Slf4j
public abstract class AbstractWorkflowApproveDetailService implements WorkflowApproveDetailServiceInterface {
    @Resource
    private WorkflowTaskModel workflowTaskModel;
    @Resource
    private WorkflowTaskNodeModel workflowTaskNodeModel;
    @Resource
    private ContractModel contractModel;
    @Resource
    private InvoiceModel invoiceModel;
    @Resource
    private PurchaseInvoiceModel purchaseInvoiceModel;
    @Resource
    private FundHelp fundHelp;
    @Resource
    private WorkflowDingtalkTodoService workflowDingtalkTodoService;
    @Resource
    private WorkflowNodeModel workflowNodeModel;
    @Resource
    private WorkflowApproveListPageService workflowApproveListPageService;
    @Resource
    private WorkOrderFormModel workOrderFormModel;
    @Resource
    private WorkOrderTemplateModel workOrderTemplateModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private UserModel userModel;
    @Resource
    private DepartmentModel departmentModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private WorkOrderExplainModel workOrderExplainModel;
    @Resource
    private PaasFormRichTextModel paasFormRichTextModel;
    @Resource
    private WorkflowModel workflowModel;
    @Resource
    private PackageHelp packageHelp;
    @Resource
    private FundMoneyHelp fundMoneyHelp;
    @Resource
    private WorkflowCommentService workflowCommentService;
    @Resource
    private FormDataFormExplainHandleName formDataFormExplainHandleName;
    @Resource
    private FormExplainHelp formExplainHelp;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private FormDataUpdateGetAnalysisDataHelp formDataUpdateGetAnalysisDataHelp;
    @Resource
    private FormDataLinkDataUpdateGetServiceImpl formDataLinkDataUpdateGetService;
    @Resource
    private EsignHelp esignHelp;
    @Resource
    private UserInfoHelp userInfoHelp;
    @Resource
    private FormatDataHelp formatDataHelp;
    //    @Resource
//    private PaasProcessDataServiceImpl paasProcessDataService;
    @Resource
    private ShowFormatHelp showFormatHelp;
    @Resource
    private WorkflowTransferDataModel workflowTransferDataModel;
    @Resource
    private FormatProductHelp formatProductHelp;
    @Resource
    private OwnerAndCoUserHelp ownerAndCoUserHelp;
    @Resource
    private CouponModel couponModel;
    @Resource
    private FundSetHelp fundSetHelp;
    @Resource
    private FormDataHelp formDataHelp;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private MongoLogHelp mongoLogHelp;

    @Resource
    private BusinessUserTeamHelp businessUserTeamHelp;
    @Resource
    private FormTeamSetHelp formTeamSetHelp;
    @Resource
    private PublicGroupSeniorModel publicGroupSeniorModel;
    @Resource
    private UserConfigHelp userConfigHelp;
    @Resource
    private WorkflowNodeHelp workflowNodeHelp;
    @Resource
    private WorkflowHelp workflowHelp;
    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private IndexTypeModel indexTypeModel;
    @Resource
    private ContractCompareUtil contractCompareUtil;
    @Resource
    private WorkflowOperateHelp workflowOperateHelp;
    @Resource
    private InvoiceExpressSubDataModel invoiceExpressSubDataModel;

    /**
     * 详情页
     *
     * @param workflowNodeTaskGetDTO
     */
    @Override
    public WorkflowNodeTaskGetVO detail(WorkflowNodeTaskGetDTO workflowNodeTaskGetDTO) throws XbbException {
        WorkflowNodeTaskGetVO workflowNodeTaskGetVO = new WorkflowNodeTaskGetVO();
        try {
            // 钉钉工作台特殊处理
            if (workflowNodeTaskGetDTO.getFromDingtalk()) {
                workflowOperateHelp.dealDingtalkParameter(workflowNodeTaskGetDTO);
            }
            workflowNodeTaskGetVO.setProcessType(workflowNodeTaskGetDTO.getProcessType());
            String corpid = workflowNodeTaskGetDTO.getCorpid();
            Long formId = workflowNodeTaskGetDTO.getFormId();
            String processType = workflowNodeTaskGetDTO.getProcessType();
            Integer businessType = workflowNodeTaskGetDTO.getBusinessType();
            Integer saasMark = workflowNodeTaskGetDTO.getSaasMark();
            Long taskId = workflowNodeTaskGetDTO.getProcessTaskId();

            // 获取当前流程主任务
            WorkflowTaskEntity workflowTaskEntity = workflowTaskModel.getByKey(workflowNodeTaskGetDTO.getProcessTaskId(), corpid);
            if (workflowTaskEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_TASK_NOT_EXIST);
            }

            //查询主表数据
            PaasFormDataEntityExt formData = getFormData(workflowTaskEntity.getDataId(), corpid, saasMark, businessType);
            if (Objects.isNull(formData)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
            }

            JSONObject formDataData = formData.getData();
            JSONObject backupData = new JSONObject();
            backupData.putAll(formDataData);
            WorkflowTransferDataEntity workflowTransferDataEntity = workflowTransferDataModel.getByTaskId(taskId, corpid);
            Integer operate = workflowTransferDataEntity.getOperate();
            workflowNodeTaskGetVO.setIsNew(Objects.equals(operate, WorkflowOperateEnum.ADD.getType()) ? 1 : 0);
            WorkflowTransferPOJO workflowTransferPOJO = JSON.parseObject(JSON.toJSONString(workflowTransferDataEntity.getData(), SerializerFeature.DisableCircularReferenceDetect), WorkflowTransferPOJO.class);
            JSONObject transferData = workflowTransferPOJO.getData().getData();
            if (StringUtil.isEmpty(transferData.getString("creatorId"))) {
                transferData.put("creatorId", formData.getCreatorId());
            }
            //子表单新建数据入transfer没有存dataid，导致判重会有问题，这边直接覆盖下子表单的数据
            if (Objects.nonNull(transferData) && Objects.nonNull(formDataData)) {
                Set<String> keySet = transferData.keySet();
                for (Map.Entry<String, Object> entry : formDataData.entrySet()) {
                    String key = entry.getKey();
                    if (key.contains(FieldAttrConstant.SUB_FORM) && keySet.contains(key)) {
                        transferData.put(key, entry.getValue());
                    }
                }
            }
            formData.setData(transferData);
            formData.setSerialNo(transferData.getString(FieldTypeEnum.SERIALNO.getAlias()));
            Long addTime = workflowTransferDataEntity.getAddTime();
            // 单据拆分前的出库单需要展示关联单据
            //新版工作流移除了
//            boolean needRefId = (Objects.equals(workflowTaskEntity.getBusinessType(), XbbRefTypeEnum.OTHER_OUTSTOCK.getCode()) || Objects.equals(workflowTaskEntity.getBusinessType(), XbbRefTypeEnum.OTHER_INSTOCK.getCode())) && Objects.nonNull(workflowTaskEntity.getStockType());

            Long formDataId = formData.getId();
            JSONObject dataJsonObject = formData.getData();
            workflowNodeTaskGetVO.setDataId(formDataId);
            //上下文流转数据中没有富文本数据,展示需要需插入
            PaasFormRichTextEntity paasFormRichTextEntity = new PaasFormRichTextEntity(workflowTaskEntity.getDataId(), corpid, formId, businessType, saasMark, DelEnum.NORMAL.getDel());
            PaasFormRichTextEntity richTextEntity = paasFormRichTextModel.getByDataId(paasFormRichTextEntity);
            if (Objects.nonNull(richTextEntity)) {
                dataJsonObject.put(RichTextEnum.RICH_TEXT.getAttr(), richTextEntity.getData());
            }

            // 工单自由流程标识
            boolean isFree = false;
            // 获取表单实体
            PaasFormEntityExt paasFormEntityExt = new PaasFormEntityExt();
            if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
                WorkOrderFormEntity workOrderFormEntity = workOrderFormModel.getByKey(formId, corpid);
                if (workOrderFormEntity == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                //工单如果是自由流程，负责人字段显示并必填，指定流程不显示
                WorkOrderTemplateEntity workOrderTemplateEntity = workOrderTemplateModel.getBykey(workOrderFormEntity.getTemplateId(), corpid);
                isFree = Objects.equals(workOrderTemplateEntity.getIsFree(), 1);
                BeanUtil.copyProperties(workOrderFormEntity, paasFormEntityExt);
                paasFormEntityExt.setSaasMark(SaasMarkEnum.SAAS.getCode());
                paasFormEntityExt.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
            } else {
                paasFormEntityExt = paasFormModel.getByKey(formId, corpid);
                if (paasFormEntityExt == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
            }

            // 获取用户部门容器
            Map<String, Object> params = BeanUtil.convertBean2Map(workflowNodeTaskGetDTO, true);
            params.remove("del");
            params.put(ParameterConstant.LEAVE_MARKS, BasicConstant.ONE);
            List<UserEntity> userList = userModel.findEntitys(params);
            params.remove(ParameterConstant.LEAVE_MARKS);
            if (userList == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.USER_NOT_EXIST);
            }

            Map<String, UserEntity> userMap = userList.stream().collect(Collectors.toMap(UserEntity::getUserId, t -> t));
            params.remove(ParameterConstant.COLUMNS);

            // department不能用del条件，有del = 2的数据
            List<DepartmentEntity> departmentList = departmentModel.findEntitys(params);
            if (departmentList == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.DEPT_NOT_EXIST);
            }
            Map<String, DepartmentEntity> departmentMap = departmentList.stream().collect(Collectors.toMap(t -> t.getId().toString(), t -> t));

            // 红冲回款，坏账用 防止dataJsonObject 防止转换过程中丢失
            JSONObject oldData = formData.getData();
            // 获取表单解释
            List<FieldAttrEntity> explainList = getPaasFormExplain(corpid, formId, businessType, dataJsonObject);


            if (Objects.equals(workflowNodeTaskGetDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue())) {
                // 待处理的人员 移动端需要DING的人员id信息
                params.clear();
                params.put("corpid", corpid);
                params.put("taskId", taskId);
                params.put("taskType", TaskTypeEnum.UNTREATED.getType());
                params.put("del", 0);
                List<WorkflowTaskNodeEntityExt> extEntities = workflowTaskNodeModel.findExtEntities(params);
                WorkflowValidateUtil.checkQueryResult(extEntities);
                List<String> unDealUserList = extEntities.stream().map(WorkflowTaskNodeEntity::getUserId).collect(Collectors.toList());
                workflowNodeTaskGetVO.setUnDealUserList(unDealUserList);
            }

            // 获取节点数据
            WorkflowTaskNodeEntity workflowTaskNodeEntity = workflowTaskNodeModel.getByKey(workflowNodeTaskGetDTO.getProcessNodeTaskId(), corpid);
            if (workflowTaskNodeEntity == null || Objects.equals(workflowTaskNodeEntity.getDel(), DelEnum.DELETE.getDel())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_TASK_NOT_EXIST);
            }

            // 查询审批模板
            WorkflowEntity workflowEntity = workflowModel.getByKey(workflowTaskEntity.getWorkflowId(), corpid);
            if (workflowEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_TEMPLATE_NOT_EXIST);
            }

            // 是否可以查看审批历史
            workflowNodeTaskGetVO.setAllowViewLog(workflowEntity.getAllowViewLog());
            workflowNodeTaskGetVO.setVersionName(workflowEntity.getVersionName());
            if (StringUtil.isEmpty(workflowEntity.getVersionName())) {
                workflowNodeTaskGetVO.setVersionName("v1");
            }

            // 节点模板
            WorkflowNodeEntityExt workflowNodeEntity = workflowNodeModel.getExtByKey(workflowTaskNodeEntity.getWorkflowNodeId(), corpid);
            if (workflowNodeEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_NODE_NOT_EXIST);
            }

            // 为了产品内的成本高级权限走一遍表单权限format
            HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
            handlerExplainDTO.setOwnerId(Collections.singletonList(formData.getOwnerId()));
            handlerExplainDTO.setCreatorId(formData.getCreatorId());
            BeanUtil.copyProperties(workflowNodeTaskGetDTO, handlerExplainDTO, false);
            handlerExplainDTO.setExplainList(explainList);
            handlerExplainDTO.setPaasFormEntityExt(paasFormEntityExt);
            handlerExplainDTO.setFormData(formData.getData());
            HandlerExplainVO handlerExplainVO = formDataFormExplainHandleName.handleExplain(handlerExplainDTO);
            if (handlerExplainVO == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            explainList = handlerExplainVO.getHeadList();

            // 解析数据信息
            // 存入系统字段到data中
            dataJsonObject.put(FieldTypeEnum.SERIALNO.getAlias(), formData.getSerialNo());
            if (formData.getDepartmentId() != null && !Objects.equals(formData.getDepartmentId(), 0L)) {
                dataJsonObject.put(FieldTypeEnum.DEPARTMENTID.getAlias(), formData.getDepartmentId());
            }
            // 获取协同人和负责人
            Integer del = DelEnum.NORMAL.getDel();
            if (Objects.equals(workflowTaskEntity.getFlowStatus(), FlowStatusEnum.REJECT.getType()) || Objects.equals(workflowTaskEntity.getFlowStatus(), FlowStatusEnum.REVOKE.getType())) {
                del = DelEnum.APPROVE_FAILED.getDel();
            }

            JSONObject ownerAndCoUser = ownerAndCoUserHelp.getOwnerIdAndCoUserId(handlerExplainDTO, saasMark, businessType, formData, userMap, del);
            dataJsonObject.putAll(ownerAndCoUser);

            // 解析新版协同人和负责人
            parseResponsibleAndCooperator(dataJsonObject, userMap);
            //这边需要兼容一下团队成员上线之后一些老数据兼容处理
            handTeamOldProcessData(dataJsonObject.getJSONArray(FieldTypeEnum.OWNERID.getAlias()), dataJsonObject.getJSONArray(FieldTypeEnum.COUSERID.getAlias()), dataJsonObject, businessType, corpid, addTime);
            // 字段权限
            ApprovalNode approvalNode = JSON.parseObject(workflowNodeEntity.getConfigData(), ApprovalNode.class);
            Map<String, FieldPermissionEntityExt> fieldPermission = approvalNode.getFieldPermission();
            //隔离模式下工作流团队字段权限处理 ：只展示团队负责人，负责人不可编辑
            if (Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), businessType) || Objects.equals(XbbRefTypeEnum.CLUE.getCode(), businessType)) {
                FormTeamSetEntity formTeamSet = formTeamSetHelp.getFormTeamSet(corpid, formId, saasMark, businessType, DistributorMarkEnum.OTHER.getCode());
                if (Objects.equals(formTeamSet.getModel(), FormPatternEnum.FORM_ISOLATION.getModel())) {
                    FieldPermissionEntityExt ownerId = fieldPermission.get("ownerId");
                    ownerId.setEditable(Constant.ZERO);
                    FieldPermissionEntityExt coUserId = fieldPermission.get("coUserId");
                    coUserId.setEditable(Constant.ZERO);
                    coUserId.setVisible(Constant.ZERO);
                }
            }
            //2020/6/10 28311 紧急封掉撤销审批后可以编辑关联字段, 之后重构发票之后可以去除掉这边的发票特殊逻辑
            boolean inpurtInvoiceFlag = Objects.equals(businessType, XbbRefTypeEnum.INVOICE.getCode());
            boolean isSaasEdit = Objects.equals(saasMark, SaasMarkEnum.SAAS.getCode()) && Objects.equals(WorkflowOperateEnum.UPDATE.getType(), workflowTransferDataEntity.getOperate());

            if (MapUtils.isNotEmpty(fieldPermission)) {
                // 解释格式format
                FormatExplainDTO formatExplainDTO = new FormatExplainDTO();
                BeanUtil.copyProperties(workflowNodeTaskGetDTO, formatExplainDTO);
                formatExplainDTO.setExplainList(explainList);
                PaasFormDataEntityExt paasFormData = new PaasFormDataEntityExt();
                paasFormData.setData(formData.getData());
                BeanUtil.copyProperties(formData, paasFormData);
                formatExplainDTO.setDataEntity(paasFormData);
                formatExplainDTO.setResult(dataJsonObject);
                if (Objects.equals(saasMark, SaasMarkEnum.SAAS.getCode())) {
                    formatExplainDTO.setFromCopy(!isSaasEdit);
                    //                    saasUpdateHelp.formatExplain(formatExplainDTO);
                    formExplainHelp.formatExplain(formatExplainDTO, null);
                    workflowNodeTaskGetVO.setSaasSpecialParamPojo(formatExplainDTO.getSaasSpecialParamPojo());
                    // 解释中数据字典值
                    explainList = proFormHelp.handleExplainList(explainList, businessType, corpid, formId);
                }
                // 根据节点权限设置编辑权限 saas数据编辑进审批不读权限
                List<FieldAttrEntity> headList;
                if (!isSaasEdit) {
                    boolean isStartNode = Objects.equals(workflowNodeEntity.getType(), NodeTypeEnum.START_PROCESS_NODE.getNodeType());
                    if (Objects.equals(workflowEntity.getUsePermission(), 1) || !isStartNode) {
                        headList = ExplainUtil.parseExplainListByFieldPermission(explainList, fieldPermission, isStartNode, businessType, true, workflowNodeTaskGetDTO.getLoginUser());
                    } else {
                        // 使用表单权限
                        headList = explainList;
                        for (FieldAttrEntity entity : explainList) {
                            if (ExplainUtil.invisibleOfScope(entity, handlerExplainDTO)) {
                                entity.setVisible(0);
                            }
                        }
                    }
                } else {
                    // 异或的解释处理
                    headList = ProcessUtil.xorExplainListByFieldPermission(explainList, fieldPermission, businessType, true, workflowNodeTaskGetDTO.getLoginUser());
                }
                boolean edit = false;
                if (Objects.equals(workflowTransferPOJO.getOperate(), WorkflowOperateEnum.ADD.getType())) {
                    params.clear();
                    params.put(StringConstant.CORPID, corpid);
                    params.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                    params.put("taskTypeIn", Arrays.asList(TaskTypeEnum.END.getType(), TaskTypeEnum.REVOKE.getType()));
                    params.put("taskId", taskId);
                    params.put("formId", workflowEntity.getFormId());
                    params.put("pageSize", 1);
                    params.put(StringConstant.COLUMNS, "id");
                    List<WorkflowTaskNodeEntity> nodeList = workflowTaskNodeModel.findEntities(params);
                    Integer count = nodeList.size();
                    if (!Objects.equals(count, BasicConstant.ZERO)) {
                        edit = false;
                    }
                    if (Objects.equals(workflowTaskNodeEntity.getTaskType(), TaskTypeEnum.AGAIN_COMMIT.getType())) {
                        // 当前任务为重新提交的任务状态，则不允许编辑
                        edit = true;
                    }
                }

                // 审批完成后不允许编辑 节点数据不是未处理和撤回状态
                boolean disable = (Objects.equals(processType, ProcessTypeEnum.TODO.getValue()) && !Objects.equals(workflowTaskNodeEntity.getTaskType(), TaskTypeEnum.UNTREATED.getType()))
                        || Objects.equals(processType, ProcessTypeEnum.HAVE_DONE.getValue())
                        // 我提交的，并且不是撤回或者回退的
                        || (Objects.equals(processType, ProcessTypeEnum.CREATE.getValue()) && !(Objects.equals(workflowTaskEntity.getFlowStatus(), FlowStatusEnum.REVOKE.getType())
                        || Objects.equals(workflowTaskEntity.getFlowStatus(), FlowStatusEnum.REJECT.getType())))
                        || (Objects.equals(processType, ProcessTypeEnum.CREATE.getValue()) && Objects.equals(WorkflowOperateEnum.UPDATE.getType(), operate))
                        || Objects.equals(processType, ProcessTypeEnum.CC.getValue())
                        || processType.equals(ProcessTypeEnum.ALL.getValue())
                        // 如果有多条撤回的，只允许最新的那条可以编辑，其他不可以编辑
                        || edit;
                List<String> featureList = packageHelp.getFeatureList(corpid);
                Integer feeType = commonHelp.getCurrentCompanyPackage(corpid);
                boolean ultimateTag = Objects.equals(feeType, PackageTypeEnum.ULTIMATE.getType());
                for (FieldAttrEntity fieldAttrEntity : headList) {
                    Integer fieldType = fieldAttrEntity.getFieldType();
                    // 工单需要根据模板判断负责人显不显示
                    if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
                        if (!isFree) {
                            //指定流程。设置负责人不可见
                            if (fieldAttrEntity.getFieldType() != null && fieldAttrEntity.getFieldType().equals(FieldTypeEnum.USER.getType())
                                    && Objects.equals(WorkOrderEnum.MANAGER_ID.getAttr(), fieldAttrEntity.getAttr())) {
                                fieldAttrEntity.setVisible(0);
                                fieldAttrEntity.setEditable(0);
                            }
                        } else {
                            if (fieldType != null && Objects.equals(fieldAttrEntity.getAttr(), WorkOrderEnum.MANAGER_ID.getAttr())) {
                                fieldAttrEntity.setEditable(0);
                            }
                        }
                    }
                    //新版工作流移除了
                    /*else if (needRefId && Objects.equals(fieldAttrEntity.getAttr(), OutstockEnum.TYPE.getAttr())) {
                        fieldAttrEntity.getItems().forEach(itemPoJo -> itemPoJo.setFieldMap(null));
                    } else if (needRefId && Objects.equals(fieldAttrEntity.getAttr(), OutstockEnum.REF_ID.getAttr()) && Objects.equals(formData.getBusinessType(), XbbRefTypeEnum.OTHER_OUTSTOCK.getCode())) {
                        fieldAttrEntity.setEditable(0);
                    } else if (needRefId && Objects.equals(fieldAttrEntity.getAttr(), InstockEnum.REF_ID.getAttr()) && Objects.equals(formData.getBusinessType(), XbbRefTypeEnum.OTHER_INSTOCK.getCode())) {
                        fieldAttrEntity.setEditable(0);
                    }*/
                    else if (Objects.equals(fieldType, FieldTypeEnum.SELECT_PRODUCT.getType()) && Objects.equals(businessType, XbbRefTypeEnum.SUPPLIER.getCode())) {
                        fieldAttrEntity.setVisible(0);
                    }

                    if (disable) {
                        fieldAttrEntity.setEditable(0);
                        if (Objects.equals(fieldType, FieldTypeEnum.SUB_FORM.getType()) || Objects.equals(fieldType, FieldTypeEnum.SINGLE_SUB_FORM.getType())
                                || Objects.equals(fieldType, FieldTypeEnum.CONTACT_NUMBER.getType()) || Objects.equals(fieldType, FieldTypeEnum.SELECT_PRODUCT.getType()) || Objects.equals(fieldType, FieldTypeEnum.SELECT_SERVICE.getType())) {
                            List<? extends FieldAttrEntity> subList = fieldAttrEntity.getSubForm().getItems();
                            for (FieldAttrEntity subAttr : subList) {
                                subAttr.setEditable(0);
                            }
                            fieldAttrEntity.getSubForm().setItems(subList);
                        }
                    }

                    // 设置创建人和创建时间的showType为0
                    if ((Objects.equals(fieldType, FieldTypeEnum.CREATORID.getType()) && !Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()))
                            || Objects.equals(fieldType, FieldTypeEnum.ADDTIME.getType())) {
                        fieldAttrEntity.setShowType(ShowTypeEnum.ALL.getCode());
                        fieldAttrEntity.setEditable(0);
                    }
                    // 字段回收站处理
                    if (Objects.equals(fieldAttrEntity.getIsOpen(), 2)) {
                        fieldAttrEntity.setVisible(0);
                    }
                    if (ExplainUtil.isSubForm(fieldType)) {
                        if (Objects.nonNull(fieldAttrEntity.getSubForm()) && Objects.nonNull(fieldAttrEntity.getSubForm().getItems())) {
                            List<? extends FieldAttrEntity> subFieldList = fieldAttrEntity.getSubForm().getItems();
                            subFieldList.forEach(item -> {
                                // 字段回收站处理
                                if (Objects.equals(item.getIsOpen(), 2)) {
                                    item.setVisible(0);
                                }
                                // 套餐逻辑，标准版本隐藏复杂字段
                                packageHelp.explainHide(featureList, item);
                                // 套餐逻辑，数据联动和联动其他表单
                                packageHelp.setPackageLimit(featureList, item);
                                // 限制公式
                                packageHelp.limitFormula(featureList, item, businessType);
                            });
                        }
                    } else {
                        // 套餐逻辑，标准版本隐藏复杂字段
                        packageHelp.explainHide(featureList, fieldAttrEntity);
                        // 套餐逻辑，数据联动和联动其他表单
                        packageHelp.setPackageLimit(featureList, fieldAttrEntity);
                        // 限制公式
                        packageHelp.limitFormula(featureList, fieldAttrEntity, businessType);
                    }

                    //根据套餐设置负责人字段属性
                    if (Objects.equals(fieldAttrEntity.getAttr(), FieldTypeEnum.OWNERID.getAlias())) {
                        if (!ultimateTag && FormOwnerUniqueEnum.getDefaultBusinessList().contains(businessType)) {
                            //只有旗舰版支持负责人唯一设置，其他版本拿默认设置
                            FormOwnerUniqueEnum formOwnerUniqueEnum = FormOwnerUniqueEnum.getFormOwnerUniqueByBus(businessType);
                            Integer multiple = formOwnerUniqueEnum.getValue();
                            fieldAttrEntity.setMultiple(multiple);
                        }
                    }
                    if (Objects.equals(fieldType, FieldTypeEnum.STAGE_THRUSTER.getType())) {
                        try {
                            String stageCode = formData.getData().getString(fieldAttrEntity.getAttr());
                            if (StringUtil.isEmpty(stageCode)) {
                                fieldAttrEntity.setItems(proFormHelp.setItem(fieldAttrEntity, paasFormEntityExt));
                            } else {
                                List<ItemPoJo> itemPoJoList = proFormHelp.setItem(fieldAttrEntity, paasFormEntityExt, formData.getData());
                                itemPoJoList = itemPoJoList.stream().filter(item -> Objects.equals(item.getEnable(), 1)).collect(Collectors.toList());
                                fieldAttrEntity.setItems(itemPoJoList);
                            }
                        } catch (Exception e) {
                            log.info("AbstractWorkflowApproveDetailService.detail 阶段字段获取阶段选项错误");
                        }
                    }
                }


                SheetTypeEnum sheetTypeEnum = fundHelp.getSheetTypeEnumByProcssData(businessType, dataJsonObject);
                boolean sheetFlag = SheetTypeEnum.validateSheet(sheetTypeEnum);
                if (sheetFlag) {
                    boolean isNew = Objects.equals(operate, WorkflowOperateEnum.ADD.getType());
                    //如果是回/付款单、其他收入/支出单，则根据数据data内的回/付款单/其他收入/支出单类型重置sheetTypeEnum（前端传过来的businessType可能没有详细区分哪种类型回/付款单/其他收入/支出单）
                    fundHelp.handlePaymentSheet(isNew, sheetTypeEnum, headList, corpid, 0);
                    fundHelp.setBySheetType(paasFormEntityExt, sheetTypeEnum);
                }

                if (inpurtInvoiceFlag) {
                    //暂时封住
                    fundHelp.handleInvoice(headList);
                } else if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode())) {
                    //处理账期
                    fundSetHelp.formatPeriod(corpid, businessType, formId, explainList);
                }
                workflowNodeTaskGetVO.setHeadList(headList);
            } else {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_PERMISSION_NOT_EXIST);
            }

            // SaaS特殊处理
            specialDealForSaas(businessType, dataJsonObject, explainList);
            Map<String, FieldAttrEntity> explainMap = new HashMap<>();
            for (FieldAttrEntity item : workflowNodeTaskGetVO.getHeadList()) {
                explainMap.put(item.getAttr(), item);
            }

            // saas业务数据格式转换 调用编辑的回显format
            if (Objects.equals(workflowTaskEntity.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                SaasAnalysisDataDTO saasAnalysisDataDTO = new SaasAnalysisDataDTO();
                BeanUtil.copyProperties(workflowNodeTaskGetDTO, saasAnalysisDataDTO);
                BeanUtil.copyProperties(workflowTaskEntity, saasAnalysisDataDTO);
                saasAnalysisDataDTO.setUserId(workflowNodeTaskGetDTO.getUserId());
                saasAnalysisDataDTO.setForProcess(true);
                formatDataHelp.formatData(saasAnalysisDataDTO, dataJsonObject);
                if (Objects.equals(businessType, XbbRefTypeEnum.INVENTORY.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.TRANSFER.getCode())) {
                    dataJsonObject.putIfAbsent(InventoryEnum.INVENTORY_TYPE.getAttr(), 2);
                }
                saasAnalysisDataDTO.setOperate(workflowTransferDataEntity.getOperate());
                formatProduct(saasAnalysisDataDTO, dataJsonObject, explainList, false);
            }
            // 解析数据信息
            ParseSingleRowDataDTO parseSingleRowDataDTO = new ParseSingleRowDataDTO();
            BeanUtil.copyProperties(workflowNodeTaskGetDTO, parseSingleRowDataDTO);
            parseSingleRowDataDTO.setDepartmentMap(departmentMap);
            parseSingleRowDataDTO.setUserMap(userMap);
            parseSingleRowDataDTO.setExplainMap(explainMap);
            parseSingleRowDataDTO.setDataJsonObject(dataJsonObject);
            parseSingleRowDataDTO.setIsProcess(true);
            ParseSingleRowDataVO parseSingleRowDataVO = formDataUpdateGetAnalysisDataHelp.parseSingleRowData(parseSingleRowDataDTO);
            if (parseSingleRowDataVO == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PARSE_SINGLE_ROW_DATA_FAILED);
            }
            dataJsonObject = parseSingleRowDataVO.getResult();
            if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
                String publicGroup = FastJsonHelper.getStringFromFormData(dataJsonObject, CustomerManagementEnum.PUBLIC_GROUP.getAttr());
                if (Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
                    publicGroup = FastJsonHelper.getStringFromFormData(dataJsonObject, ClueEnum.PUBLIC_GROUP.getAttr());
                }
                if (StringUtil.isNotEmpty(publicGroup)) {
                    PublicGroupSeniorEntity publicGroupSeniorEntity = publicGroupSeniorModel.getByKey(Long.valueOf(publicGroup), corpid);
                    if (Objects.nonNull(publicGroupSeniorEntity)) {
                        dataJsonObject.put(CustomerManagementEnum.PUBLIC_GROUP.getAttr(), publicGroupSeniorEntity.getName());
                    }
                }
            }
            // 关联查询
            LinkResultDataVO linkResultDataVO = parseSingleRowDataVO.getLinkResultDataVO();
            // 获取关联数据的信息
            if (linkResultDataVO != null && !linkResultDataVO.getLinkData().isEmpty() && !linkResultDataVO.getLinkDataSet().isEmpty()) {
                linkResultDataVO.setData(dataJsonObject);
                linkResultDataVO.setExplainMap(explainMap);
                linkResultDataVO.setExplainList(explainList);
                linkResultDataVO.setUserMap(userMap);
                linkResultDataVO.setDepartmentMap(departmentMap);
                FormDataUpdateGetDTO formDataUpdateGetDTO = new FormDataUpdateGetDTO();
                BeanUtil.copyProperties(workflowNodeTaskGetDTO, formDataUpdateGetDTO);
                dataJsonObject = formDataLinkDataUpdateGetService.formDataLinkDataGet(formDataUpdateGetDTO, linkResultDataVO);
            }

            //只有发票、回/付款单才有明细，其他收入、其他支出无明细
            boolean sheetFlag = Objects.equals(businessType, XbbRefTypeEnum.PAYMENT_SHEET.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.PAY_SHEET.getCode());
            boolean invoiceFlag = Objects.equals(businessType, XbbRefTypeEnum.INVOICE.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.PURCHASE_INVOICE.getCode());
            if (sheetFlag || invoiceFlag) {
                String saasNeedPojoStr = JSON.toJSONString(workflowTransferDataEntity.getSaasNeedPojo(), SerializerFeature.DisableCircularReferenceDetect);
                SaasNeedRedundantAttrPojo saasNeedPojo = JSONObject.parseObject(saasNeedPojoStr, SaasNeedRedundantAttrPojo.class);
                JSONArray amountDetail = Objects.nonNull(saasNeedPojo) ? saasNeedPojo.getAmountDetail() : null;
                //二期不用去数据库取金额明晰直接 调用方法自动生成范围 三期改造销项发票时可以直接用这种方法
                if (Objects.equals(businessType, XbbRefTypeEnum.PURCHASE_INVOICE.getCode())) {
                    amountDetail = purchaseInvoiceModel.approveGetAmountDetail(corpid, businessType, backupData, formData.getId(), saasNeedPojoStr);
                }
                if (Objects.equals(businessType, XbbRefTypeEnum.INVOICE.getCode())) {
                    amountDetail = invoiceModel.approveGetSalesAmountDetail(corpid, businessType, backupData, formData.getId(), saasNeedPojoStr);
                    //获取发票的开票信息和寄送信息，这两个存在单独的一张表里
                    List<InvoiceExpressSubDataEntity> expressSubDataEntityList = invoiceExpressSubDataModel.getByDataId(formDataId, corpid);
                    if (CollectionsUtil.isNotEmpty(expressSubDataEntityList)){
                        for (PaasFormSubDataEntity invoiceExpressSubDataEntity : expressSubDataEntityList) {
                            JSONObject data = invoiceExpressSubDataEntity.getData();
                            //开票信息需要把下拉框字段处理
                            if (Objects.equals(invoiceExpressSubDataEntity.getAttr(),"subForm_1")) {
                                String titleValue = data.getString("text_1");
                                ItemPoJo itemPoJo = new ItemPoJo();
                                itemPoJo.setText(InvoiceTitleTypeEnum.getNameByValue(titleValue));
                                itemPoJo.setValue(titleValue);
                                data.put("text_1", itemPoJo);
                            }
                            dataJsonObject.put(invoiceExpressSubDataEntity.getAttr(),Arrays.asList(data));
                        }
                    }
                }
                if (sheetFlag && Objects.isNull(amountDetail)) {
                    JSONObject data = formData.getData();
                    //回/付款单，没有明细则渲染一个默认的明细（把父单的data信息塞入明细即可）
                    amountDetail = fundHelp.getDefaultAmountDetail(data, null);
                }
                dataJsonObject.put(PaasConstant.AMOUNTDETAIL, amountDetail);
                if (invoiceFlag) {
                    String originIdAttr = "";
                    if (Objects.equals(businessType, XbbRefTypeEnum.INVOICE.getCode())) {
                        originIdAttr = InvoiceEnum.ORIGIN_ID.getAttr();
                    } else if (Objects.equals(businessType, XbbRefTypeEnum.PURCHASE_INVOICE.getCode())) {
                        originIdAttr = PurchaseInvoiceEnum.ORIGIN_ID.getAttr();
                    }
                    if (dataJsonObject.containsKey(originIdAttr)) {
                        JSONArray originArray = null;
                        if (Objects.equals(businessType, XbbRefTypeEnum.INVOICE.getCode())) {
                            originArray = dataJsonObject.getJSONArray(InvoiceEnum.ORIGIN_ID.getAttr());
                        } else if (Objects.equals(businessType, XbbRefTypeEnum.PURCHASE_INVOICE.getCode())) {
                            originArray = dataJsonObject.getJSONArray(PurchaseInvoiceEnum.ORIGIN_ID.getAttr());
                        }
                        JSONObject originJson = null;
                        if (CollectionsUtil.isNotEmpty(originArray)) {
                            originJson = originArray.getJSONObject(0);
                        }

                        SaasSpecialParamPojo saasSpecialParamPojo = workflowNodeTaskGetVO.getSaasSpecialParamPojo();
                        if (Objects.isNull(workflowNodeTaskGetVO.getSaasSpecialParamPojo())) {
                            saasSpecialParamPojo = new SaasSpecialParamPojo();
                        }
                        if (Objects.nonNull(originJson)) {
                            if (originJson.getLong(BasicConstant.ID) > BasicConstant.ZERO) {
                                saasSpecialParamPojo.setFromRed(BasicConstant.ONE);
                                workflowNodeTaskGetVO.setSaasSpecialParamPojo(saasSpecialParamPojo);
                                if (CollectionsUtil.isNotEmpty(workflowNodeTaskGetVO.getHeadList())) {
                                    for (FieldAttrEntity fieldAttrEntity : workflowNodeTaskGetVO.getHeadList()) {
                                        if (Objects.equals(fieldAttrEntity.getSaasAttr(), InvoiceEnum.TOTAL_MONEY.getSaasAttr())) {
                                            fieldAttrEntity.setAttrName(InvoiceConstant.REDSTRING + fieldAttrEntity.getAttrName());
                                        }
                                    }
                                }
                                if (Objects.equals(businessType, XbbRefTypeEnum.PURCHASE_INVOICE.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.INVOICE.getCode())) {
                                    InvoiceCommonHelp.getMinusAmountFormRedInvoice(dataJsonObject, amountDetail, originJson.getLong(BasicConstant.ID), BasicConstant.ZERO, businessType);
                                }
                            } else {
                                saasSpecialParamPojo.setFromRed(BasicConstant.ZERO);
                                workflowNodeTaskGetVO.setSaasSpecialParamPojo(saasSpecialParamPojo);
                            }
                        }
                    }
                    if (Objects.equals(businessType, XbbRefTypeEnum.INVOICE.getCode())) {
                        fundMoneyHelp.setPrePaymentSheetType(dataJsonObject, corpid);
                    } else if (Objects.equals(businessType, XbbRefTypeEnum.PURCHASE_INVOICE.getCode())) {
                        fundMoneyHelp.setPrePaySheetType(dataJsonObject, corpid);
                    }
                }
            }
            //*****************************************************************

            // node任务的vo对象
            PaasProcessNodeTaskVO paasProcessNodeTaskVO = new PaasProcessNodeTaskVO();
            BeanUtil.copyProperties(workflowTaskNodeEntity, paasProcessNodeTaskVO);
            paasProcessNodeTaskVO.setSaasMark(workflowTaskEntity.getSaasMark());
            if (Objects.nonNull(workflowTaskNodeEntity.getWorkflowNodeId())) {
                paasProcessNodeTaskVO.setTemplateNodeId(workflowTaskNodeEntity.getWorkflowNodeId());
            }
            paasProcessNodeTaskVO.setOpinionFlag(approvalNode == null ? null : approvalNode.getOpinionFlag());
            paasProcessNodeTaskVO.setBusinessType(workflowTaskEntity.getBusinessType());

            UserEntity commitUserEntity = userMap.get(workflowTaskEntity.getCreatorId());
            if (Objects.nonNull(commitUserEntity)) {
                UserVO commitUser = new UserVO();
                BeanUtil.copyProperties(commitUserEntity, commitUser);
                workflowNodeTaskGetVO.setCommitUser(commitUser);
                if (Objects.equals(businessType, XbbRefTypeEnum.INVOICE.getCode())) {
                    paasFormEntityExt.setName(XbbRefTypeEnum.INVOICE.getName());
                }
                workflowNodeTaskGetVO.setTitle(commitUserEntity.getName().replace("(离职)", "") + I18nMessageUtil.getMessage(CommonConstant.OF) + paasFormEntityExt.getName() + I18nMessageUtil.getMessage(I18nStringConstant.APPROVAL));
                paasProcessNodeTaskVO.setCreatorUser(commitUser);

            } else {
                // 人员离职
                workflowNodeTaskGetVO.setTitle("***" + I18nMessageUtil.getMessage(CommonConstant.OF) + paasFormEntityExt.getName() + I18nMessageUtil.getMessage(I18nStringConstant.APPROVAL));
                UserVO commitUser = new UserVO();
                BeanUtil.copyProperties(workflowNodeTaskGetDTO.getLoginUser(), commitUser);
                commitUser.setName("***(" + I18nMessageUtil.getMessage(I18nStringConstant.RESIGNED) + ")");
                commitUser.setUserId("0");
                workflowNodeTaskGetVO.setCommitUser(commitUser);
                paasProcessNodeTaskVO.setCreatorUser(commitUser);
            }
            if (StringUtil.isNotEmpty(workflowTaskNodeEntity.getTitle())) {
                workflowNodeTaskGetVO.setTitle(workflowTaskNodeEntity.getTitle());
            }

            // 转交和撤回人
            if (StringUtil.isNotEmpty(paasProcessNodeTaskVO.getTransferUserId()) && userMap.containsKey(paasProcessNodeTaskVO.getTransferUserId())) {
                UserVO userVO = new UserVO();
                BeanUtil.copyProperties(userMap.get(paasProcessNodeTaskVO.getTransferUserId()), userVO);
                paasProcessNodeTaskVO.setTransferUser(userVO);

            }
            if (StringUtil.isNotEmpty(paasProcessNodeTaskVO.getRevokeUserId()) && userMap.containsKey(paasProcessNodeTaskVO.getRevokeUserId())) {
                UserVO userVO = new UserVO();
                BeanUtil.copyProperties(userMap.get(paasProcessNodeTaskVO.getRevokeUserId()), userVO);
                paasProcessNodeTaskVO.setRevokeUser(userVO);
            }

            // 节点任务中文描述
            paasProcessNodeTaskVO.setTaskTypeMemo(TaskTypeEnum.getStatusMemo(paasProcessNodeTaskVO.getTaskType()));
            TaskTypeEnum taskTypeEnum = TaskTypeEnum.getTaskTypeEnum(paasProcessNodeTaskVO.getTaskType());
            if (taskTypeEnum != null) {
                paasProcessNodeTaskVO.setColor(taskTypeEnum.getColor());
            }
            if (Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.PURCHASE.getCode())) {
                boolean isNew = Objects.equals(operate, WorkflowOperateEnum.ADD.getType());
                Double writeOffAmount = 0D;
                if (!isNew) {
                    FormDataUpdateGetDTO formDataUpdateGetDTO = new FormDataUpdateGetDTO();
                    BeanUtil.copyProperties(workflowNodeTaskGetDTO, formDataUpdateGetDTO);
                    formDataUpdateGetDTO.setDataId(formDataId);
                    writeOffAmount = fundMoneyHelp.getCoverCalAmount(formDataUpdateGetDTO, explainMap, businessType);
                }
                workflowNodeTaskGetVO.setWriteOffAmount(writeOffAmount);
            }
            // 创建时间
            dataJsonObject.put(FieldTypeEnum.ADDTIME.getAlias(), formData.getAddTime());
            // saas特殊处理
            saasSpecialHandle(paasProcessNodeTaskVO, dataJsonObject, workflowNodeTaskGetVO, businessType);
            workflowNodeTaskGetVO.setProcessNodeTask(paasProcessNodeTaskVO);
            workflowNodeTaskGetVO.setName(paasFormEntityExt.getName());
            workflowNodeTaskGetVO.setData(dataJsonObject);
            workflowNodeTaskGetVO.setFlowStatus(workflowTaskEntity.getFlowStatus());
            workflowNodeTaskGetVO.setSerialNo(formData.getSerialNo());
            workflowNodeTaskGetVO.setFlowStatusDesc(FlowStatusEnum.getMemoByType(workflowTaskEntity.getFlowStatus()));

            // 流程操作 未处理或者是被撤回的流程
            if (TaskTypeEnum.UNTREATED.getType().equals(workflowTaskNodeEntity.getTaskType())
                    || FlowStatusEnum.REVOKE.getType().equals(workflowTaskEntity.getFlowStatus())
                    || NodeTypeEnum.START_PROCESS_NODE.getNodeType().equals(workflowTaskNodeEntity.getNodeType())
                    || TaskTypeEnum.SYSTEM_COMMIT.getType().equals(workflowTaskNodeEntity.getTaskType())
                    || FlowStatusEnum.inApproval().contains(workflowTaskEntity.getFlowStatus())) {
                // 同意、撤回等操作
                workflowOperateHelp.getProcessOperator(workflowNodeEntity, workflowNodeTaskGetDTO, workflowNodeTaskGetVO, workflowEntity, workflowTaskNodeEntity, userMap, workflowTransferPOJO);
            } else {
                workflowNodeTaskGetVO.setProcessOperatePermission(new ProcessTemplateNodeVO());
            }
            //判断查看全流程权限
            Integer allowViewWhole = workflowEntity.getAllowViewWhole();
            if (Objects.equals(allowViewWhole, EnableEnum.OPEN.getCode()) && FlowStatusEnum.inApproval().contains(workflowTaskEntity.getFlowStatus()) && Objects.equals(workflowNodeTaskGetDTO.getPlatform(), PlatFormEnum.WEB.getValue())) {
                List<ProcessOperateVo> processOperate = workflowNodeTaskGetVO.getProcessOperatePermission().getProcessOperate();
                processOperate = Objects.isNull(processOperate) ? new ArrayList<>() : processOperate;
                processOperate.add(new ProcessOperateVo(Constant.ONE, TaskTypeEnum.VIEW_WHOLE_PROCESS.getMemo(), TaskTypeEnum.VIEW_WHOLE_PROCESS.getType()));
            }
            // 增加流程用时
            long processTime;
            if (workflowTaskEntity.getFlowStatus().equals(FlowStatusEnum.PASS.getType())
                    || workflowTaskEntity.getFlowStatus().equals(FlowStatusEnum.REJECT.getType())
                    || workflowTaskEntity.getFlowStatus().equals(FlowStatusEnum.REVOKE.getType())
                    || workflowTaskEntity.getFlowStatus().equals(FlowStatusEnum.REFUSE.getType())) {
                processTime = workflowTaskEntity.getUpdateTime() - workflowTaskEntity.getAddTime();
            } else {
                processTime = DateUtil.getInt() - workflowTaskEntity.getAddTime();
            }
            workflowNodeTaskGetVO.setProcessTime(processTime);

            //流程合同比对
            if ((Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.PURCHASE.getCode()))
                    && Objects.equals(workflowNodeTaskGetDTO.getPlatform(), PlatFormEnum.WEB.getValue())
                    && processType.equals(ProcessTypeEnum.TODO.getValue())) {
                Boolean compareButton = contractCompareUtil.showCompareButton(corpid, workflowNodeTaskGetDTO.getLoginUser().getPermSet(), workflowNodeTaskGetDTO.getUserId());
                if (compareButton) {
                    ProcessOperateVo operatePoJo = new ProcessOperateVo();
                    operatePoJo.setText(TaskTypeEnum.CONTRACT_COMPARE.getMemo());
                    operatePoJo.setFlag(1);
                    operatePoJo.setType(TaskTypeEnum.CONTRACT_COMPARE.getType());
                    workflowNodeTaskGetVO.getProcessOperatePermission().getProcessOperate().add(operatePoJo);
                }
            }

            // 流程评论权限
            if (workflowNodeTaskGetDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.PROCESS_COMMENT.getAlias())) {
                ProcessOperateVo operatePoJo = new ProcessOperateVo();
                operatePoJo.setText(TaskTypeEnum.PROCESS_COMMENT.getMemo());
                operatePoJo.setFlag(1);
                operatePoJo.setType(TaskTypeEnum.PROCESS_COMMENT.getType());
                if (!Objects.equals(workflowNodeTaskGetDTO.getPlatform(), PlatFormEnum.WEB.getValue())) {
                    if (workflowNodeTaskGetVO.getProcessOperatePermission().getProcessOperate().size() < 3) {
                        workflowNodeTaskGetVO.getProcessOperatePermission().getProcessOperate().add(operatePoJo);
                    } else {
                        workflowNodeTaskGetVO.getProcessOperatePermission().getProcessOperate().add(2, operatePoJo);
                    }
                } else {
                    workflowNodeTaskGetVO.getProcessOperatePermission().getProcessOperate().add(operatePoJo);
                }
            }
            // ding权限
            if (Objects.equals(workflowNodeTaskGetDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue()) &&
                    (processType.equals(ProcessTypeEnum.TODO.getValue()) || processType.equals(ProcessTypeEnum.CREATE.getValue()))) {
                ProcessOperateVo operatePoJo = new ProcessOperateVo();
                operatePoJo.setText("DING");
                operatePoJo.setFlag(1);
                workflowNodeTaskGetVO.getProcessOperatePermission().getProcessOperate()
                        .add(workflowNodeTaskGetVO.getProcessOperatePermission().getProcessOperate().size(), operatePoJo);
            }
            Set<String> loginUserPermSet = workflowNodeTaskGetDTO.getLoginUser().getPermSet();
            // 移动端添加打印按钮
            boolean hasPrint = false;
            if (Objects.equals(SaasMarkEnum.SAAS.getCode(), workflowNodeTaskGetDTO.getSaasMark())) {
                PrintProPermissionAliasEnum printProPermissionAliasEnum = PrintProPermissionAliasEnum.getByCode(businessType);
                hasPrint = Objects.nonNull(printProPermissionAliasEnum) && loginUserPermSet.contains(printProPermissionAliasEnum.getAlias());
            } else {
                PermissionTermsPojo paasFormPermission = ProPermissionHelp.getPaasFormPermission(workflowNodeTaskGetDTO.getLoginUser(), paasFormEntityExt.getAppId(), paasFormEntityExt.getMenuId());
                hasPrint = Objects.equals(paasFormPermission.getPrint(), BasicConstant.ONE);
            }
            if (Objects.equals(workflowNodeTaskGetDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue()) && hasPrint) {
                ProcessOperateVo operatePoJo = new ProcessOperateVo();
                operatePoJo.setType(TaskTypeEnum.PRINT.getType());
                operatePoJo.setText(I18nMessageUtil.getMessage(PaasConstant.PRINT));
                operatePoJo.setFlag(1);
                if (CollectionsUtil.isNotEmpty(workflowNodeTaskGetVO.getProcessOperatePermission().getProcessOperate())) {
                    workflowNodeTaskGetVO.getProcessOperatePermission().getProcessOperate()
                            .add(workflowNodeTaskGetVO.getProcessOperatePermission().getProcessOperate().size() - 1, operatePoJo);
                }
            }
            // 删除流程权限
            if ((workflowNodeTaskGetDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.PROCESS_DELETE.getAlias())
                    && Objects.equals(workflowNodeTaskGetDTO.getProcessType(), ProcessTypeEnum.CREATE.getValue()))
                    || Objects.equals(workflowNodeTaskGetDTO.getProcessType(), ProcessTypeEnum.ALL.getValue())) {
                workflowNodeTaskGetVO.setDelFlag(1);
            }
            // 打印权限
            boolean printFlag;
            XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.PAAS;
            if (Objects.equals(SaasMarkEnum.SAAS.getCode(), workflowNodeTaskGetDTO.getSaasMark())) {
                printFlag = ProPermissionHelp.hasPrintPermission(businessType, workflowNodeTaskGetDTO.getLoginUser());
                xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
            } else {
                PermissionTermsPojo permissionTerms = ProPermissionHelp.getPaasFormPermission(workflowNodeTaskGetDTO.getLoginUser(), workflowNodeTaskGetDTO.getAppId(), workflowNodeTaskGetDTO.getMenuId());
                printFlag = Objects.equals(BasicConstant.ONE, permissionTerms.getPrint()) || workflowNodeTaskGetDTO.getLoginUser().isAdminOrBoss();
            }

            if (printFlag) {
                workflowNodeTaskGetVO.setPrintFlag(BasicConstant.ONE);
            }

            if (Objects.equals(businessType, XbbRefTypeEnum.REFUND.getCode()) && Objects.equals(workflowNodeTaskGetVO.getFlowStatus(), FlowStatusEnum.APPROVAL_PENDING.getType())
                    && Objects.equals(paasFormEntityExt.getDistributorMark(), DistributorMarkEnum.DISTRIBUTOR.getCode())) {
                JSONObject data = workflowNodeTaskGetVO.getData();
                JSONObject orderJson = data.getJSONArray(ReturnEnum.ORDER_ID.getAttr()).getJSONObject(0);
                ContractEntityExt contractEntityExt = contractModel.getByKey(orderJson.getLongValue(StringConstant.SAAS_LINK_BUSINESS_ID), corpid);
                if (contractEntityExt != null) {
                    JSONObject couponData = contractEntityExt.getData();
                    JSONArray couponId = couponData.getJSONArray(OrderEnum.COUPON_ID.getAttr());
                    List<Long> couponIdList = new ArrayList<>();
                    if (CollectionUtils.isNotEmpty(couponId)) {
                        for (int i = 0; i < couponId.size(); i++) {
                            couponIdList.add(couponId.getLongValue(i));
                        }
                        List<CouponEntity> coupons = couponModel.findEntitysByIdIn(couponIdList, corpid);
                        if (CollectionUtils.isNotEmpty(coupons)) {
                            StringBuilder sb = new StringBuilder();
                            for (int i = 0; i < coupons.size(); i++) {
                                sb.append(coupons.get(i).getName()).append(",");
                            }
                            sb.deleteCharAt(sb.length() - 1);
                            data.put(ReturnEnum.RETURN_TIPS.getSaasAttr(), sb);
                        }
                    }
                }
            }

            //无需审批或审批通过的数据才可能签署
            if ((Objects.equals(workflowNodeTaskGetVO.getFlowStatus(), FlowStatusEnum.NOT_NEED_APPROVAL.getType()) ||
                    Objects.equals(workflowNodeTaskGetVO.getFlowStatus(), FlowStatusEnum.PASS.getType()))) {

                PermissionTermsPojo paasFormPermission = ProPermissionHelp.getPaasFormPermission(workflowNodeTaskGetDTO.getLoginUser(), paasFormEntityExt.getAppId(), paasFormEntityExt.getMenuId());

                if (esignHelp.hasEsignPermission(paasFormPermission, workflowNodeTaskGetDTO.getLoginUser().isAdminOrBoss(), workflowNodeTaskGetDTO.getLoginUser().getPermSet(), xbbRefTypeEnum, corpid, formId)) {

                    EsignFlowStatusDTO esignFlowStatusDTO = new EsignFlowStatusDTO();
                    BeanUtil.copyProperties(workflowNodeTaskGetDTO, esignFlowStatusDTO);
                    esignFlowStatusDTO.setCorpid(corpid);
                    esignFlowStatusDTO.setFormId(formId);
                    esignFlowStatusDTO.setDataId(formDataId);
                    EsignFlowStatusVO esignFlowStatusVO = null;
                    try {
                        esignFlowStatusVO = esignHelp.getEsignFlowStatus(esignFlowStatusDTO);
                    } catch (XbbException e) {
                        //                        return ;
                    }
                    Integer code = esignFlowStatusVO.getCode();
                    EsignFlowStatusEnum esignFlowStatusEnum = EsignFlowStatusEnum.getByCode(code);
                    switch (esignFlowStatusEnum) {
                        case COMPLETE:
                        case SIGNING:
                            //没有下载
                            break;
                        case UNSIGNED:
                        case DRAFT:
                        case UNDO:
                        case TERMINATION:
                        case EXPIRED:
                        case REFUSAL:
                            workflowNodeTaskGetVO.setEsignFlag(BasicConstant.ONE);
                            if (Objects.equals(workflowNodeTaskGetDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue())) {
                                ProcessOperateVo operatePoJo = new ProcessOperateVo();
                                operatePoJo.setText(TaskTypeEnum.ESIGN.getMemo());
                                operatePoJo.setFlag(1);
                                operatePoJo.setType(TaskTypeEnum.ESIGN.getType());
                                workflowNodeTaskGetVO.getProcessOperatePermission().getProcessOperate().add(operatePoJo);
                            }

                            break;
                        default:
                            break;
                    }
                }

            }


        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            log.error("工作流审批详情页出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return workflowNodeTaskGetVO;
    }

    /**
     * 解析新版负责人和协同人
     *
     * @param dataJsonObject
     * @param userMap
     */
    private void parseResponsibleAndCooperator(JSONObject dataJsonObject, Map<String, UserEntity> userMap) {
        JSONArray ownIdList = dataJsonObject.getJSONArray(FieldTypeEnum.OWNERID.getAlias());
        JSONArray coUserIdList = dataJsonObject.getJSONArray(FieldTypeEnum.COUSERID.getAlias());
        if (CollectionsUtil.isNotEmpty(ownIdList)) {
            List<ReturnUserAndDepartmentPojo> ownList = new ArrayList<>();
            for (Object o : ownIdList) {
                if (o == null) {
                    continue;
                }
                String id;
                if (o instanceof JSONObject) {
                    id = ((JSONObject) o).getString(StringConstant.SAAS_LINK_BUSINESS_ID);
                } else {
                    id = o.toString();
                }
                UserEntity user = userMap.get(id);
                ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                if (Objects.nonNull(user)) {
                    BeanUtil.copyProperties(user, returnUserAndDepartmentPojo);
                    returnUserAndDepartmentPojo.setId(user.getUserId());
                    ownList.add(returnUserAndDepartmentPojo);
                }
            }
            dataJsonObject.put(FieldTypeEnum.OWNERID.getAlias(), ownList);
        }

        if (CollectionsUtil.isNotEmpty(coUserIdList)) {
            List<ReturnUserAndDepartmentPojo> coUserList = new ArrayList<>();
            for (Object o : coUserIdList) {
                if (o == null) {
                    continue;
                }
                String id = (String) o;
                UserEntity user = userMap.get(id);
                ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                if (Objects.nonNull(user)) {
                    BeanUtil.copyProperties(user, returnUserAndDepartmentPojo);
                    returnUserAndDepartmentPojo.setId(user.getUserId());
                    coUserList.add(returnUserAndDepartmentPojo);
                }
            }
            dataJsonObject.put(FieldTypeEnum.COUSERID.getAlias(), coUserList);
        }
    }

    /**
     * 获取解释
     *
     * @param corpid
     * @param formId 表单id
     * @param businessType
     * @param data 流程数据，用于拿到一些解释
     * @return
     * @throws XbbException
     */
    @Override
    public List<FieldAttrEntity> getPaasFormExplain(String corpid, Long formId, Integer businessType, JSONObject data) throws XbbException {
        PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
        if (Objects.equals(businessType, XbbRefTypeEnum.PAYMENT_SHEET.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.PAY_SHEET.getCode())) {
            paasFormExplainEntity = paasFormExplainModel.getByBusinessType(businessType, corpid);
        } else if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
            WorkOrderExplainEntityExt workOrderExplainEntityExt = workOrderExplainModel.getByFormId(formId, corpid);
            if (workOrderExplainEntityExt == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            BeanUtil.copyProperties(workOrderExplainEntityExt, paasFormExplainEntity);
            paasFormExplainEntity.setSaasMark(SaasMarkEnum.SAAS.getCode());
            paasFormExplainEntity.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
        } else {
            paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
        }
        if (paasFormExplainEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        return JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
    }

    public void specialDealForSaas(Integer businessType, JSONObject dataJsonObject, List<FieldAttrEntity> explainList) throws XbbException {
        if (Objects.equals(businessType, XbbRefTypeEnum.INVOICE.getCode())) {
            // 红冲发票解释处理和data处理
            String orginIdAttr = InvoiceEnum.ORIGIN_ID.getAttr();
            Integer originId = dataJsonObject.getInteger(orginIdAttr);
            if (originId != null && originId > 0) {
                explainList.forEach(item -> {
                    if (Objects.equals(item.getAttr(), orginIdAttr)) {
                        item.setShowType(ShowTypeEnum.ALL.getCode());
                        item.setEditable(0);
                    } else if (Objects.equals(item.getAttr(), InvoiceEnum.CUSTOMER_NAME.getAttr())) {
                        item.setEditable(0);
                    }
                });
                showFormatHelp.formatLinkBusiness4Show(dataJsonObject, orginIdAttr, InvoiceEnum.ORIGIN_ID_LINK_TEXT.getAttr(), InvoiceEnum.ORIGIN_ID.getFieldType());
            }
        }
    }


    private void saasSpecialHandle(PaasProcessNodeTaskVO paasProcessNodeTaskVO, JSONObject dataJsonObject, WorkflowNodeTaskGetVO workflowNodeTaskGetVO, Integer businessType) throws XbbException {
        if (Objects.equals(businessType, XbbRefTypeEnum.QUOTATION.getCode())) {
            String version = FastJsonHelper.getStringOrDefaultFromFormData(dataJsonObject, QuotationEnum.VERSION.getAttr(), StringConstant.DEFAULT_VERSION);
            String groupNumber = FastJsonHelper.getStringOrDefaultFromFormData(dataJsonObject, QuotationEnum.GROUP_NUMBER.getAttr(), "");
            if (!Objects.equals(version, StringConstant.DEFAULT_VERSION)) {
                // 如果报价单版本号不是1.0，那么他就是创建新版本,新版本名称判重有些特殊（组号相同的不盘虫）
                JSONObject newVersionObj = new JSONObject();
                newVersionObj.put("newVersion", BasicConstant.ONE);
                newVersionObj.put(QuotationEnum.GROUP_NUMBER.getSaasAttr(), groupNumber);
                List<FieldAttrEntity> headList = workflowNodeTaskGetVO.getHeadList();
                if (null != headList) {
                    headList.forEach(item -> {
                        if (Objects.equals(item.getAttr(), QuotationEnum.NAME.getAttr())) {
                            item.setQuotationNameRepeat(newVersionObj);
                        }
                    });
                }
                paasProcessNodeTaskVO.setQuotationNameRepeat(newVersionObj);
            }
        }
    }

    /**
     * 处理团队成员上线之后，一些业务团队放出来之后，需要在审批那边做个特殊处理兼容一下
     * 具体需要处理的业务有：回款单、付款单、联系人、供应商联系人
     * 回款单：客户（text_6 字符串）、合同（text_4 数组）
     *
     * @param ownIdList      负责人id列表
     * @param coUserIdList   协同人列表
     * @param dataJsonObject 审批数据
     * @param businessType   业务类型
     * @param corpid         公司id
     */
    private void handTeamOldProcessData(JSONArray ownIdList, JSONArray coUserIdList, JSONObject dataJsonObject, Integer businessType, String corpid, Long addTime) {
        boolean specialHandTag = Objects.equals(businessType, XbbRefTypeEnum.PAYMENT_SHEET.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.PAY_SHEET.getCode()) ||
                Objects.equals(businessType, XbbRefTypeEnum.CONTACT.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.SUPPLIER_CONTACT.getCode());
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        Integer parentBusinessType = null;
        if (specialHandTag) {
            if ((Objects.isNull(ownIdList) || ownIdList.size() == BasicConstant.ZERO) &&
                    (Objects.isNull(coUserIdList) || coUserIdList.size() == BasicConstant.ZERO)) {
                if (Objects.equals(businessType, XbbRefTypeEnum.CONTACT.getCode()) && addTime > TeamMembersConstant.OLD_TIME_DATA) {
                    return;
                }
                Map<Long, List<String>> mainUserIdMap = new HashMap<>();
                Map<Long, List<String>> coUserIdMap = new HashMap<>();
                Object customerOrSupplierObj = null;
                Object contractOrSupplierContractObj = null;
                Set<String> userIdList = new HashSet<>();
                switch (xbbRefTypeEnum) {
                    case PAYMENT_SHEET:
                        customerOrSupplierObj = Long.valueOf(dataJsonObject.getString(PaymentSheetEnum.CUSTOMER_ID.getAttr()));
                        contractOrSupplierContractObj = dataJsonObject.getJSONArray(PaymentSheetEnum.CONTRACT.getAttr());
                        break;
                    case PAY_SHEET:
                        customerOrSupplierObj = Long.valueOf(dataJsonObject.getString(PaySheetEnum.LINK_SUPPLIER.getAttr()));
                        contractOrSupplierContractObj = dataJsonObject.getJSONArray(PaySheetEnum.LINK_PURCHASE.getAttr());
                        break;
                    case CONTACT:
                        customerOrSupplierObj = Long.valueOf(dataJsonObject.getString(ContactEnum.CUSTOMER_NAME.getAttr()));
                        contractOrSupplierContractObj = dataJsonObject.getString(ContactEnum.CUSTOMER_NAME_LINK_TEXT.getAttr());
                        break;
                    case SUPPLIER_CONTACT:
                        customerOrSupplierObj = Long.valueOf(dataJsonObject.getString(SupplierContactEnum.SUPPLIER_ID.getAttr()));
                        contractOrSupplierContractObj = dataJsonObject.getString(SupplierContactEnum.SUPPLIER_ID_LINK_TEXT.getAttr());
                        break;
                }
                //判断contractOrSupplierContractObj是不是为空
                boolean contactOrSupplierContactTag = Objects.equals(XbbRefTypeEnum.CONTACT, xbbRefTypeEnum) || Objects.equals(XbbRefTypeEnum.SUPPLIER_CONTACT, xbbRefTypeEnum);
                boolean preSheetTag = false;
                if (Objects.equals(XbbRefTypeEnum.PAYMENT_SHEET, xbbRefTypeEnum) || Objects.equals(XbbRefTypeEnum.PAY_SHEET, xbbRefTypeEnum)) {
                    if (Objects.equals(dataJsonObject.get(PaymentConstant.ATTR_SHEET_TYPE), SheetTypeEnum.PREPAYMENT.getCode())
                            || Objects.equals(dataJsonObject.get(PaymentConstant.ATTR_SHEET_TYPE), SheetTypeEnum.RED_PREPAYMENT.getCode())) {
                        //付款单、回款单  如果是预收预付类型，也是获取客户和供应商团队
                        preSheetTag = true;
                    }
                }
                if (contactOrSupplierContactTag || preSheetTag) {
                    boolean flage = true;
                    if (Objects.isNull(customerOrSupplierObj)) {
                        flage = false;
                    }
                    if (!flage) {
                        return;
                    }

                    //说明需要获取客户或供应商的负责人团队
                    if (Objects.equals(businessType, XbbRefTypeEnum.CONTACT.getCode()) ||
                            Objects.equals(businessType, XbbRefTypeEnum.PAYMENT_SHEET.getCode())) {
                        parentBusinessType = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
                    } else {
                        parentBusinessType = XbbRefTypeEnum.SUPPLIER.getCode();
                    }
                    if (Objects.nonNull(customerOrSupplierObj)) {
                        businessUserTeamHelp.getUserIdMapSetShow(userIdList, Arrays.asList((long) customerOrSupplierObj), corpid, parentBusinessType, false, mainUserIdMap,
                                coUserIdMap, BasicConstant.ZERO);
                        List<String> mainUserList = mainUserIdMap.get((long) customerOrSupplierObj);
                        List<String> coUserList = coUserIdMap.get((long) customerOrSupplierObj);
                        packageTeamInfo(mainUserList, coUserList, dataJsonObject, corpid);
                    }
                }

                boolean paymentOrPaymentsheetTag = Objects.equals(XbbRefTypeEnum.PAYMENT_SHEET, xbbRefTypeEnum) || Objects.equals(XbbRefTypeEnum.PAY_SHEET, xbbRefTypeEnum);
                if (paymentOrPaymentsheetTag) {
                    boolean flage = true;
                    if (Objects.isNull(contractOrSupplierContractObj)) {
                        flage = false;
                    } else if (contractOrSupplierContractObj instanceof JSONArray) {
                        if (((JSONArray) contractOrSupplierContractObj).size() == BasicConstant.ZERO) {
                            flage = false;
                        }
                    }
                    if (!flage) {
                        return;
                    }
                    //说明需要获取合同或则采购合同的负责人团队
                    if (Objects.equals(businessType, XbbRefTypeEnum.PAYMENT_SHEET.getCode())) {
                        parentBusinessType = XbbRefTypeEnum.CONTRACT.getCode();
                    } else {
                        parentBusinessType = XbbRefTypeEnum.PURCHASE.getCode();
                    }
                    if (Objects.nonNull(contractOrSupplierContractObj)) {
                        List<Long> dataIdList = JSONObject.parseArray(((JSONArray) contractOrSupplierContractObj).toJSONString(), Long.class);
                        businessUserTeamHelp.getUserIdMapSetShow(userIdList, dataIdList, corpid, parentBusinessType, false, mainUserIdMap,
                                coUserIdMap, BasicConstant.ZERO);
                        List<String> finalOwnerStrList = new ArrayList<>();
                        List<String> finalCoUserStrList = new ArrayList<>();
                        for (Long dataId : dataIdList) {
                            List<String> ownerIdStrList = Objects.isNull(mainUserIdMap.get(dataId)) ? new ArrayList<>() : mainUserIdMap.get(dataId);
                            List<String> coUserIdStrList = Objects.isNull(coUserIdMap.get(dataId)) ? new ArrayList<>() : coUserIdMap.get(dataId);
                            ownerIdStrList.removeAll(finalOwnerStrList);
                            ownerIdStrList.removeAll(finalCoUserStrList);
                            coUserIdStrList.removeAll(finalOwnerStrList);
                            coUserIdStrList.removeAll(finalCoUserStrList);
                            finalOwnerStrList.addAll(ownerIdStrList);
                            finalCoUserStrList.addAll(coUserIdStrList);
                        }
                        packageTeamInfo(finalOwnerStrList, finalCoUserStrList, dataJsonObject, corpid);
                    }
                }
            }
        }

    }

    /**
     * 封装团队返回信息
     *
     * @param finalOwnerStrList
     * @param finalCouserStrList
     * @param dataJsonObject
     * @param corpid
     */
    private void packageTeamInfo(List<String> finalOwnerStrList, List<String> finalCouserStrList, JSONObject dataJsonObject, String corpid) {
        List<String> finalStrList = new ArrayList<>();
        if (CollectionsUtil.isNotEmpty(finalOwnerStrList)) {
            finalStrList.addAll(finalOwnerStrList);
        }
        if (CollectionsUtil.isNotEmpty(finalCouserStrList)) {
            finalStrList.addAll(finalCouserStrList);
        }
        if (CollectionsUtil.isNotEmpty(finalStrList)) {
            Map<String, UserEntity> userEntityMap = userModel.getUserEntityMap(corpid, finalStrList, BasicConstant.ONE);
            if (Objects.nonNull(userEntityMap)) {
                if (CollectionsUtil.isNotEmpty(finalOwnerStrList)) {
                    List<ReturnUserAndDepartmentPojo> ownList = new ArrayList<>();
                    for (String userId : finalOwnerStrList) {
                        UserEntity userEntity = userEntityMap.get(userId);
                        ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                        if (Objects.nonNull(userEntity)) {
                            BeanUtil.copyProperties(userEntity, returnUserAndDepartmentPojo);
                            returnUserAndDepartmentPojo.setId(userEntity.getUserId());
                            ownList.add(returnUserAndDepartmentPojo);
                        }
                    }
                    dataJsonObject.put(FieldTypeEnum.OWNERID.getAlias(), ownList);
                }
                if (CollectionsUtil.isNotEmpty(finalCouserStrList)) {
                    List<ReturnUserAndDepartmentPojo> coList = new ArrayList<>();
                    for (String userId : finalCouserStrList) {
                        UserEntity userEntity = userEntityMap.get(userId);
                        ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                        if (Objects.nonNull(userEntity)) {
                            BeanUtil.copyProperties(userEntity, returnUserAndDepartmentPojo);
                            returnUserAndDepartmentPojo.setId(userEntity.getUserId());
                            coList.add(returnUserAndDepartmentPojo);
                        }
                    }
                    dataJsonObject.put(FieldTypeEnum.COUSERID.getAlias(), coList);
                }
            }
        }
    }


    @Override
    public void formatProduct(SaasAnalysisDataDTO saasAnalysisDataDTO, JSONObject data, List<FieldAttrEntity> explainList, boolean formCopy) throws XbbException {
        formatProductHelp.formatProduct(saasAnalysisDataDTO, data, explainList, formCopy);
    }

    /**
     * 获取数据
     * @param dataId
     * @param corpid
     * @param saasMark
     * @param businessType
     * @return
     * @throws XbbException
     */
    @Override
    public PaasFormDataEntityExt getFormData(Long dataId, String corpid, Integer saasMark, Integer businessType) throws XbbException {
        return formDataHelp.getFormData( corpid, saasMark, businessType, dataId);
    }
}